﻿using System;
using DDotNet.Data.BusinessObjects;
using DDotNet.Data.BusinessObjects.Core;
using DDotNet.Data.BusinessObjects.Validation;
using DDotNet.Data.CodeGen.Model.Factory;
using DDotNet.Data.CodeGen.Model.Struct;

namespace DDotNet.Data.CodeGen.Model.Entity.Abstract
{
    public abstract class AbstractUser : BusinessBase<User>
    {
        #region Constructor

        public AbstractUser()
        {
        }

        #endregion

        #region Fields Declaration

        private UserStruct _Fields = new UserStruct();
        
        #endregion

        #region Properties

        /// <summary>
        /// Contém o ID do Projeto
        /// </summary>
        public int ID
        {
            get
            {
                CanReadProperty("ID", true);
                return this._Fields.id;
            }
        }

        /// <summary>
        /// Contém o Nome do Projeto
        /// </summary>
        public string UserIdentification
        {
            get
            {
                CanReadProperty("UserIdentification", true);
                return this._Fields.userIdentification;
            }
            set
            {
                CanWriteProperty("UserIdentification", true);
                if (value == null)
                {
                    value = string.Empty;
                }
                if (this._Fields.userIdentification != value)
                {
                    this._Fields.userIdentification = value;
                    PropertyHasChanged("UserIdentification");
                }
            }
        }

        #endregion

        #region Validation Methods

        /// <summary>
        /// Método para Indicar se a Entidade pode ser Excluída
        /// </summary>
        public override void CanDeleteObject()
        {
            base.CanDeleteObject();
        }

        /// <summary>
        /// Método para Indicar se a Entidade por ser Criada/Adicionada
        /// </summary>
        public override void CanAddObject()
        {
            base.CanAddObject();
        }

        /// <summary>
        /// Método para Indicar se a Entidade por ser Alterada
        /// </summary>
        public override void CanEditObject()
        {
            base.CanEditObject();
        }

        #endregion

        #region Custom Save

        /// <summary>
        /// Saves the object to the database.
        /// </summary>
        /// <remarks>
        /// <para>
        /// Calling this method starts the save operation, causing the object
        /// to be inserted, updated or deleted within the database based on the
        /// object's current state.
        /// </para><para>
        /// If <see cref="BusinessBase.IsDeleted" /> is <see langword="true"/>
        /// the object will be deleted. Otherwise, if <see cref="BusinessBase.IsNew" /> 
        /// is <see langword="true"/> the object will be inserted. 
        /// Otherwise the object's data will be updated in the database.
        /// </para><para>
        /// All this is contingent on <see cref="BusinessBase.IsDirty" />. If
        /// this value is <see langword="false"/>, no data operation occurs. 
        /// It is also contingent on <see cref="BusinessBase.IsValid" />. 
        /// If this value is <see langword="false"/> an
        /// exception will be thrown to indicate that the UI attempted to save an
        /// invalid object.
        /// </para><para>
        /// It is important to note that this method returns a new version of the
        /// business object that contains any data updated during the save operation.
        /// You MUST update all object references to use this new version of the
        /// business object in order to have access to the correct object data.
        /// </para><para>
        /// You can override this method to add your own custom behaviors to the save
        /// operation. For instance, you may add some security checks to make sure
        /// the user can save the object. If all security checks pass, you would then
        /// invoke the base Save method via <c>base.Save()</c>.
        /// </para>
        /// </remarks>
        /// <returns>A new object containing the saved values.</returns>
        public override User Save()
        {
            try
            {
                if (IsDeleted) // Deleted Entity
                {
                    CanDeleteObject();
                }
                else if (IsNew) // New Entity
                {
                    CanAddObject();
                }
                else // Old Entity
                {
                    CanEditObject();
                }
            }
            catch (ValidationException e)
            {
                throw e;
            }

            return base.Save();
        }

        #endregion

        #region Data Access

        #endregion

        #region DataPortal Overrides

        /// <summary>
        /// Override this method to load a new business object with default
        /// values from the database.
        /// </summary>
        /// <remarks>
        /// Normally you will overload this method to accept a strongly-typed
        /// criteria parameter, rather than overriding the method with a
        /// loosely-typed criteria parameter.
        /// </remarks>
        /// <param name="criteria">An object containing criteria values.</param>
        [RunLocal()]
        protected override void DataPortal_Create(object criteria)
        {
            _Fields.id = int.MinValue;
            _Fields.userIdentification = string.Empty;
            ValidationRules.CheckRules();            
        }

        /// <summary>
        /// Override this method to allow retrieval of an existing business
        /// object based on data in the database.
        /// </summary>
        /// <remarks>
        /// Normally you will overload this method to accept a strongly-typed
        /// criteria parameter, rather than overriding the method with a
        /// loosely-typed criteria parameter.
        /// </remarks>
        /// <param name="criteria">An object containing criteria values to identify the object.</param>
        protected override void DataPortal_Fetch(object criteria)
        {
            base.DataPortal_Fetch(criteria);
        }

        /// <summary>
        /// Override this method to allow insertion of a business
        /// object.
        /// </summary>
        protected override void DataPortal_Insert()
        {
            base.DataPortal_Insert();
        }

        /// <summary>
        /// Override this method to allow update of a business
        /// object.
        /// </summary>
        protected override void DataPortal_Update()
        {
            base.DataPortal_Update();
        }

        /// <summary>
        /// Override this method to allow deferred deletion of a business object.
        /// </summary>
        protected override void DataPortal_DeleteSelf()
        {
            base.DataPortal_DeleteSelf();
        }

        /// <summary>
        /// Override this method to allow immediate deletion of a business object.
        /// </summary>
        /// <param name="criteria">An object containing criteria values to identify the object.</param>
        protected override void DataPortal_Delete(object criteria)
        {
            base.DataPortal_Delete(criteria);
        }

        #endregion

    }
}